<?
/**
 * Applet functions
 */
(basename($_SERVER['PHP_SELF']) == basename(__FILE__)) && die('Access Denied');

/**
 * Disable a user account.
 * @return void
 */
function actionDisable() {
	// requirements
	global $_APP;
	requireWebApp();

	// Callback
	$callback = 'getPageView';

	// pull uid and property name from request vars
	$id = $_APP->html->getCrumb(WA_QS_ID);
	if (!is_numeric($id) or $id < 1) {
		$_APP->html->addError('Invalid ID specified.');
		die($callback());
		}

	// Look up the object
	$uo = getDbo('User');
	$uo->resetProperties();
	if ($uo->populateFromDb($id) === false) {
		$_APP->html->addError('Failed to locate the user.');
		die($callback());
		}

	// User already disabled?
	if ($uo->IsDisabled()) {
		$_APP->html->addError('User already disabled.');
		die($callback());
		}

	// Do the deed
	$auid = $_APP->getAuthenticatedUserId();
	$uo->setProperty('Enabled', '0');
	$uo->setProperty('RevUid', $auid);
	$uo->setProperty('RevDate', 'now()');
	$uo->setProperty('DisableUid', $auid);
	$uo->setProperty('DisableDate', 'now()');
	$rc = $uo->update();
	if (!($rc === true)) {
		$_APP->html->addError($rc);
		die($callback());
		}

	// Log the results
	$m = 'disable user(' . $uo->getProperty('Login') . ')';
	$_APP->log->log_audit($m);
	die($callback());
	}

/**
 * Enable a user account.
 * @return void
 */
function actionEnable() {
	// requirements
	global $_APP;
	requireWebApp();

	// Callback
	$callback = 'getPageView';

	// pull uid and property name from request vars
	$id = $_APP->html->getCrumb(WA_QS_ID);
	if (!is_numeric($id) or $id < 1) {
		$_APP->html->addError('Invalid ID specified.');
		die($callback());
		}

	// Look up the object
	$uo = getDbo('User');
	$uo->resetProperties();
	if ($uo->populateFromDb($id) === false) {
		$_APP->html->addError('Failed to locate the user.');
		die($callback());
		}

	// User already disabled?
	if ($uo->IsEnabled()) {
		$_APP->html->addError('User already enabled.');
		die($callback());
		}

	// Do the deed
	$auid = $_APP->getAuthenticatedUserId();
	$uo->setProperty('Enabled', '1');
	$uo->setProperty('RevUid', $auid);
	$uo->setProperty('RevDate', 'now()');
	$uo->setProperty('DisableUid', '1');
	$uo->setProperty('DisableDate', '0000-00-00 00:00:00');
	$rc = $uo->update();
	if (!($rc === true)) {
		$_APP->html->addError($rc);
		die($callback());
		}

	// Log the results
	$m = 'enable user(' . $uo->getProperty('Login') . ')';
	$_APP->log->log_audit($m);
	die($callback());
	}

/**
 * Reset user's password.
 */
function actionPassReset() {
	global $_APP;
	requireWebApp();

	// Pull out the id
	$id = $_APP->html->getCrumb(WA_QS_ID);
	if (!is_numeric($id) or $id < 1) {
		$_APP->html->addError('User ID not specified.');
		die($_APP->html->getTemplate('password.reset.confirm.php'));
		}

	// Look up the object
	$dbo = getDbo('User');
	$dbo->resetProperties();
	if ($dbo->populateFromDb($id) === false) {
		$_APP->html->addError('Failed to locate the account.');
		die($_APP->html->getTemplate('password.reset.confirm.php'));
		}

	// Get temporary password
	$tmpPass = $_APP->auth->getTemporaryPassword();
	$_APP->html->setVar('tmpPass', $tmpPass);
	$_APP->html->setVar('item', $dbo);

	// Set password...
	if (defined('PASS_SALT')) {
		$md5pass = md5(PASS_SALT . ':' . $tmpPass);
		} else {
		$md5pass = md5($tmpPass);
		}
	$dbo->setProperty('Password', $md5pass);

	// Submit the changes...
	$dbo->populated = true;
	$rc = $dbo->update();
	if (!($rc === true)) {
		$_APP->html->addError($rc);
		}

	die($_APP->html->getTemplate('password.reset.confirm.php'));
	}

/**
 * Toggle a user property
 * Use to change toggle a user property between on and off.  Will change the
 * current property to its opposite value.  Will return to the user view page.
 * Pulls property name from WA_QS_PROPERTY request var, user id from WA_QS_ID.
 * @return void
 */
function actiontoggleProperty() {
	// requirements
	global $_APP;
	requireWebApp();

	// Callback
	$callback = 'getPageView';

	// pull uid and property name from request vars
	$id = $_APP->html->getCrumb(WA_QS_ID);
	if (!is_numeric($id) or $id < 1) {
		die($_APP->html->getPageError('Invalid UID specified.'));
		}

	// Pull out the property name to be toggled
	$propertyName = $_APP->html->getRequestVar(WA_QS_PROPERTY);

	// acceptable toggles
	$props = array('IsAdmin');
	if (!in_array($propertyName, $props)) {
		$_APP->html->addError('Cannot toggle that property.');
		die($callback());
		}

	// Look up the object
	$uo = getDbo('User');
	$uo->resetProperties();
	if ($uo->populateFromDb($id) === false) {
		$_APP->html->addError('Failed to locate the user.');
		die($callback());
		}

	// Get current property value so we know what to change it to, for logging,
	// etc...
	switch($uo->getProperty($propertyName)) {
		case '0':
			$newProp = '1';
			$desc    = 'on';
		break;
		case '1':
			$newProp = '0';
			$desc    = 'off';
		break;
		default:
			$m = 'Current property is set to invalid value.';
			$_APP->html->addError($m);
			die($callback());
		break;
		}

	// Do the deed
	$auid = $_APP->getAuthenticatedUserId();
	$rc = $uo->setFlag($propertyName, $newProp);
	if (!($rc === true)) {
		$_APP->html->addError($rc);
		die($callback());
		}

	// Log the results
	$m = 'toggle user(' . $uo->getProperty('Login') . ') '
	. 'property(' . $propertyName . '): ' . $desc;
	$_APP->log->log_audit($m);
	die($callback());
	}

/**
 * Get menu bar local to this applet
 * @param string $currentPage
 * @param bool canDelete
 * @return string
 */
function getMenuBar($currentPage = null, $canDelete = false) {
	global $_APP;

	// All possible links
	$add = new menuLink($_APP->html->getActionQs(ACTION_ADD),
	                    'images/add32.png',
	                    OPT_ADD,
	                    ($currentPage == OPT_ADD));
	$back = new menuLink($_APP->html->getActionQs(ACTION_LIST),
	                     'images/left.png',
	                     OPT_BACK);
	$del  = new menuLink($_APP->html->getActionQs(ACTION_DEL),
	                     'images/trash32.png',
	                     OPT_DEL,
	                     ($currentPage == OPT_DEL));
	$dn  = new menuLink($_APP->html->getActionQs(ACTION_LIST)
	                    . '&' . WA_QS_DOWNLOAD . '=yes',
	                    'images/download32.png',
	                    OPT_DOWN);
	$edit = new menuLink($_APP->html->getActionQs(ACTION_EDIT),
	                     'images/edit32.png',
	                     OPT_EDIT,
	                     ($currentPage == OPT_EDIT));
	$view = new menuLink($_APP->html->getActionQs(ACTION_VIEW),
	                     'images/view32.png',
	                     OPT_VIEW,
	                     ($currentPage == OPT_VIEW));
	$sm = new menuBar();
	// different pages get different options
	switch($currentPage) {
		case OPT_ADD:
			$sm->addToRight($back);
			$sm->addToRight($add);
		break;
		case OPT_LIST:
		case OPT_BACK:
			$sm->addToRight($dn);
			$sm->addToRight($add);
		break;
		default:
			$sm->addToRight($back);
			$sm->addToRight($edit);
			$sm->addToRight($view);
			if ($canDelete === true) { $sm->addToRight($del); }
			$sm->addToRight($add);
		break;
		}
    return $sm->get();
	}

/**
 * Get main and local menu bars.
 * @param string $currentPage
 * @param bool canDelete
 * @return string
 */
function getMenuBars($currentPage = null, $canDelete = false) {
	return getMenuBarMain(OPT_ADMIN) . getMenuBar($currentPage, $canDelete);
	}

/**
 * Render page and process request to add users
 * @return void
 */
function getPageAdd() {
	// requirements
	global $_APP;
	requireWebApp();

	// objects we need
	$user = getDbo('User');
	$user->resetProperties();
	$user->populateFromPost();

	// Set up the html template
	$_APP->html->addJs('js/util.js');
	$_APP->html->addJs('js/add.user.js');
	$_APP->html->setVar('user', $user);

	// Has user confirmed?
	if (!$_APP->html->hasConfirmed()) {
		die($_APP->html->getTemplate('add.php'));
		}

	// Verify the username does not already exist...
	$un = $user->getProperty('Login');
	$user->searchReset();
	$user->setSearchSelect('Id');
	$user->setSearchFilter('Login', $un);
	$user->setSearchLimit('1');
	$q = $user->query();
	if (!is_array($q)) {
		$_APP->html->addError('Failed to determine if username already '
		. 'exists.');
		die($_APP->html->getTemplate('add.php'));
		}
	if (count($q) > 0) {
		$m = $user->getPropertyDescription('Login') . ' already '
		. 'exists, try another.';
		$_APP->html->addError($m);
		die($_APP->html->getTemplate('add.php'));
		}

	// Submit the changes
	$user->populated = true;

	// translate checkbox properties
	$props = array('Enabled', 'IsAdmin');
	foreach($props as $prop) {
		$flag = (isset($_POST[$prop])) ? '1' : '0';
		$user->setProperty($prop, $flag);
		}

	// require the password to be reset via the view screen
	$user->setProperty('Password', '*');

	// do it
	$auid = $_APP->getAuthenticatedUserId();
	$user->setProperty('CreateUid', $auid);
	$user->setProperty('RevUid', $auid);
	if ($user->IsDisabled()) {
		$user->setProperty('DisableUid', $auid);
		$user->setProperty('DisableDate', 'now()');
		}
	$rc = $user->add();
	if (!($rc === true)) {
		$_APP->html->addError($rc);
		die($_APP->html->getTemplate('add.php'));
		}

	// Log
	$m = 'add user(' . $user->getProperty('Login') . ')';
	$_APP->log->log_audit($m);

	// View the results
	$_APP->html->setCrumb(WA_QS_ID, $user->getProperty('Id'));
	die(getPageView());
	}

/**
 * Render page and process requests to delete users
 * @return void
 */
function getPageDelete() {
	// requirements first
	global $_APP;
	requireWebApp();

	// pull out the id
	$id = $_APP->html->getCrumb(WA_QS_ID);
	if (!is_numeric($id) or $id < 1) {
		die('FATAL ERROR: id not specified');
		}

	// Look up the object
	$uo = getDbo('User');
	$uo->resetProperties();
	if ($uo->populateFromDb($id) === false) {
		die($_APP->html->getPageError('Failed to locate the user.'));
		}
	$_APP->html->setVar('item', $uo);

	// callback page
	$callback = 'getPageView';

	// Has the user confirmed?
	if (!$_APP->html->hasConfirmed()) {
		die($_APP->html->getTemplate('delete.confirm.php'));
		}

	// Do the nasty
	$rc = $uo->delete();
	if (!($rc === true)) {
		$_APP->html->addError($rc);
		die($callback());
		}

	// Log it
	$m = 'delete uid(' . $uo->Id() . ') login(' . $uo->Login() . ') '
	   . 'name(' . $uo->Name() . ')';
	$_APP->log->log_audit($m);

	// Strip the delete bread crumbs
	$_APP->html->deleteCrumb(WA_QS_ACTION);
	$_APP->html->deleteCrumb(WA_QS_ID);

	// Reload the list page
	die(getPageList());
	}

/**
 * Render page and process requests to edit users
 * @return void
 */
function getPageEdit() {
	// requirements first
	global $_APP;
	requireWebApp();

	// pull out the id
	$id = $_APP->html->getCrumb(WA_QS_ID);
	if (!is_numeric($id) or $id < 1) {
		die('FATAL ERROR: id not specified');
		}

	// Look up the object
	$uo = getDbo('User');
	$uo->resetProperties();
	if ($uo->populateFromDb($id) === false) {
		die($_APP->html->getPageError('Failed to locate the user.'));
		}

	// Apply changes from user input
	$uo->populateFromPost();

	// set return url
	$_APP->returnUrlSet($_APP->html->getActionQs(ACTION_EDIT));

	// Set up the html template
	$_APP->html->addJs('js/util.js');
	$_APP->html->addJs('js/edit.user.js');
	$_APP->html->setVar('user', $uo);

	// Has the user confirmed?
	if (!$_APP->html->hasConfirmed()) {
		die($_APP->html->getTemplate('edit.php'));
		}

	// Save the changes
	$rc = $uo->update();
	if (!($rc === true)) {
		$_APP->html->addError($rc);
		die($_APP->html->getTemplate('edit.php'));
		}

	// Log
	$m = 'edit user(' . $uo->getProperty('Login') . ') '
	. 'account properties';
	$_APP->log->log_audit($m);

	// View the results
	die(getPageView());
	}

/**
 * Generate data and load list template when listing user accounts
 * @return void
 */
function getPageList() {
	// requirements
	global $_APP;
	requireWebApp();

	// Overwrite this, we may be called from getPageDelete()
	$_APP->html->setCrumb(WA_QS_ACTION, ACTION_LIST);

	// obtain object and set list properties
	$dbo = getDbo('User');
	if ($_APP->html->downloadRequested()) {
		$props = getListDownloadProperties($dbo);
		} else {
		$props = array('Id', 'Login', 'DisplayName', 'FirstName', 'LastName');
		}
	$_APP->html->setPropertiesList($props);

	// search properties
	$sprops = array('BuiltIn', 'DisplayName', 'FirstName', 'IsAdmin',
	'Enabled', 'LastName', 'Login');
	foreach($sprops as &$prop) {
		$_APP->html->addSearchProperty($prop);
		}

	// Default search property and order
	$_APP->html->setSearchPropertyDefault('Login');
	$_APP->html->setSearchOrderDefault('Login');

	// Reset search and apply user input
	$dbo->searchReset();
	$_APP->html->setUserInput($dbo);

	// Do the query
	$_APP->html->doQueryList($dbo);

	// Take care of download requests
	if ($_APP->html->downloadRequested()) {
		$h = array();
		// first line contains field names
		$h[] = '"' . implode('","', $props) . '"';
		foreach($_APP->html->searchResults as &$row) {
			$r = str_replace('"', '""', $row);
			$h[] = '"' . implode('","', $r) . '"';
			}
		$txt = implode("\r\n",$h) . "\r\n";
		unset($h);
		die($_APP->html->uploadContent($txt, 'user-list.csv'));
		}

	// set up the html template
	$_APP->html->setVar('list', $dbo);
	die($_APP->html->getTemplate('list.php'));
	}

/**
 * Generate data and load list template when viewing user accounts
 * @return void
 */
function getPageView() {
	// requirements
	global $_APP;
	requireWebApp();

	// get objects we need
	$dbo = getDbo('User');

	// populate the user
	$id = $_APP->html->getCrumb(WA_QS_ID);
	$dbo->resetProperties();
	$rc = $dbo->populateFromDb($id);
	if (!($rc === true)) {
		die($_APP->html->getPageError('Failed to locate the user'));
		}

	// set return url
	$_APP->returnUrlSet($_APP->html->getActionQs(ACTION_VIEW));

	// Create/Disable/Revise Users
	$uo = clone $dbo;
	$uo->resetProperties();
	$uo->populateFromDb($dbo->CreateUid());
	$CreateUser = $uo->Login();

	$uo->resetProperties();
	$uo->populateFromDb($dbo->DisableUid());
	$DisableUser = $uo->Login();

	$uo->resetProperties();
	$uo->populateFromDb($dbo->RevUid());
	$RevUser = $uo->Login();

	// set up the html template
	$_APP->html->setVar('item', $dbo);
	$_APP->html->setVar('CreateUser', $CreateUser);
	$_APP->html->setVar('DisableUser', $DisableUser);
	$_APP->html->setVar('RevUser', $RevUser);
	die($_APP->html->getTemplate('view.php'));
	}
?>
